<?php
/**
 * Создания групы файлов, директории на основе директории с шаблонами.
 *
 * Если файлы и директории существуют в результатирующий директории
 * их перезапись не происходит, создаються только не существующие
 * директории и файлы.
 *
 *
 * @author   nrnwest@gmail.com
 */
class Arm_File_BuilderWithTemplates
{

    /**
     * Путь к директории с шаблонами
     *
     * @var string
     */
    private $_dirTemplates;

    /**
     * Путь к результатирующие директории
     *
     * @var string
     */
    private $_resultDir;

    /**
     * Масив для поиска
     *
     * @var array
     */
    private $_searshArray = array();

    /**
     * Масив для заменны
     *
     * @var array
     */
    private $_replaceArray = array();

    /**
     * Коснтруктор
     *
     * @param sting  $dirPatterns путь к директории с шаблонами
     * @param string $resultDir   путь к результатирующим директория
     * @param array  $arraySearshReplace Масив поиска и заменны
     * @param int    $modeResulDir права на использования директории 0777 ...
     */
    public function __construct($dirTemplates, $resultDir,  $arraySearshReplace=array(), $modeResulDir = 0644)
    {
        if(false === is_dir($dirTemplates))  {
            throw new Arm_File_Exception(Arm_Translate::_('Не существует директории c шаблонами %s',$dirTemplates));
        }

        $this->_dirTemplates = $dirTemplates;

        if (false === is_dir($resultDir)) {

            $res = mkdir($resultDir, $modeResulDir);
            if ($res === false) {
                throw new Arm_File_Exception(Arm_Translate::_('Система не смогла создать результатирующею директорию %s', $resultDir));
            }

        }

        $this->_resultDir = $resultDir;

        foreach ($arraySearshReplace as $k=>$v) {
            $this->_searshArray[] = $k;
            $this->_replaceArray[] = $v;
        }


    }


    /**
     * Получения всех директории с директории шаблонов
     *
     * @param string $path
     * @param string $result
     * @return array
     */
    public function getDirsTemplate($path=null, $result = array())
    {
        if ($path === null) {
            $path = $this->_dirTemplates;
        }
        $array = glob($path . '*', GLOB_ONLYDIR);
        if ($array !== false) {
            $result = array_merge($result, $array);
            foreach ($array as $v) {
                $result =  $this->getDirsTemplate($v . DIRECTORY_SEPARATOR, $result);
            }
        }
        return $result;
    }


    /**
     * Получения всех файлов с директории шаблонов
     *
     * @param array $dirs директории
     */
    public function getFilesTemplate(array $dirs)
    {
        $dirs[] = $this->_dirTemplates;

        $result = array();
        foreach ($dirs as $v) {
           $res =  glob($v . DIRECTORY_SEPARATOR . '*');
           foreach ($res as $file) {
              if(is_file($file)) {
                  $result[] = $file;
              }
           }
        }
        return $result;
    }


    /**
     * Выполнение
     *
     * @return void
     */
    public function run()
    {
         // Создаем директории все которые не существуют в результатирующей
         // директории
         $dirs = $this->getDirsTemplate();
         foreach ($dirs as $dir) {
           $newDir = $this->replace($dir);
           $newDir = $this->replacePath($newDir);
           if (is_dir($newDir)) {
               continue;
           }

           mkdir($newDir);

         }

         // Создания всех файлов
         foreach ($this->getFilesTemplate($dirs) as $file) {
             // Перепишем контент файла
             $content  = file_get_contents($file, false);
             $content  = $this->replace($content);
             $pathFile = $this->replace($file);
             $pathFile = $this->replacePath($pathFile);
             if (is_file($pathFile)) {
                 continue;
             }
             $fp = fopen($pathFile, 'wb');
             fwrite($fp, $content);
             fclose($fp);
         }
    }

    /**
     * Поиск и заменна в строке данных устновленных в конструкторе
     *
     * @param string $str
     * @return string
     */
    public function replace($str)
    {
        return str_replace($this->_searshArray, $this->_replaceArray, $str);
    }

    /**
     * Перезапись путей - директорий файлов
     *
     * @param  string $path
     * @return string
     */
    public function replacePath($path)
    {
        return $this->_resultDir . ltrim(str_replace($this->_dirTemplates, '',  $path), '/\\');
    }
}